package com.xbongbong.pro.statistics.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.xbongbong.paas.pojo.dto.FixDataJobDTO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.wrap.XbbResponse;
import com.xbongbong.pro.config.ProBaseConfig;
import com.xbongbong.pro.constant.XbbProConstant;
import com.xbongbong.pro.domain.entity.ChartCategoryEntity;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.global.ChartCategoryEnum;
import com.xbongbong.pro.statistic.enums.ChartCategoryTypeEnum;
import com.xbongbong.pro.statistic.model.ChartCategoryModel;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author zcp
 * @version v1.0
 * @since v1.0
 */
@RestController
@RequestMapping(value = XbbProConstant.API_ROOT_PREFIX + "/script/chart/category")
public class ChartCategoryScriptController {
    private static final Logger LOG = LoggerFactory.getLogger(ChartCategoryScriptController.class);
    @Resource
    private ProBaseConfig proBaseConfig;
    @Resource
    private ChartCategoryModel chartCategoryModel;

    /**
     * 新增分类
     * @param fixDataJobDTO
     * @return java.lang.String
     * @throws Exception
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    @RequestMapping(value = "/performance/add", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String performanceAdd(@RequestBody @Valid FixDataJobDTO fixDataJobDTO) throws Exception {
        try {
            if (!proBaseConfig.getXbbCode().equals(fixDataJobDTO.getXbbCode())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006);
            }
            List<String> corpidList = fixDataJobDTO.getCorpidList();
            if (CollectionsUtil.isEmpty(corpidList)) {
                // 获取所有公司
                corpidList = chartCategoryModel.getCorpidList();
            }
            LOG.warn("-----------performanceAdd start 开始执行图表中心目标完成情况分类增加-----------");
            long timeStart = DateTimeUtil.getInt();
            int total = corpidList.size();
            int pageSize = 500;
            XbbResponse<JSONObject> response;
            JSONObject resultJson = new JSONObject();
            /*
              前提：原系统的图表中心目标完成情况，alias已经由“performanceChart”改为“systemPerformanceChart”，名字变为“系统目标”
              新增一级分类：目标完成情况，alias定为“performanceChart”
             */
            int type = ChartCategoryTypeEnum.PERFORMANCE.getCode();
            ChartCategoryEnum performanceChart = ChartCategoryEnum.PERFORMANCE_FINISH_CHART;
            String alias = performanceChart.getAlias();
            Map<String, Object> param = Maps.newHashMapWithExpectedSize(BasicConstant.FIVE);
            param.put("del", 0);
            param.put("type", type);
            param.put("alias", alias);
            param.put(StringConstant.COLUMNS, "corpid");
            //新增的一级分类“目标完成情况”与原系统目标的英文名及占位(sort)保持一致
            String nameEn = "Target accomplishment";
            int sort = 45;
            for (int i = 0; i < total; i += pageSize) {
                int toIndex = i + pageSize;
                if (toIndex > total) {
                    toIndex = total;
                }
                List<String> subList;
                try {
                    subList = corpidList.subList(i, toIndex);
                } catch (Exception e) {
                    LOG.info("{}", e);
                    resultJson.put("err", "错误 error");
                    response = new XbbResponse<>(resultJson);
                    return JSON.toJSONString(response);
                }
                if (CollectionUtils.isEmpty(subList)) {
                    break;
                }
                param.put("corpidIn", subList);
                List<ChartCategoryEntity> list = chartCategoryModel.findEntitys(param);
                //已经增加过新分类的公司id集合
                List<String> addEdCorpidList = list.stream().map(c->c.getCorpid()).collect(Collectors.toList());
                List<ChartCategoryEntity> insertList = new ArrayList<>();
                for (String corpid : subList) {
                    if (addEdCorpidList.contains(corpid)) {
                        continue;
                    }
                    ChartCategoryEntity newChartCategoryEntity = new ChartCategoryEntity(corpid, type, performanceChart, nameEn, sort);
                    newChartCategoryEntity.setCreatorId("");
                    insertList.add(newChartCategoryEntity);
                }
                int insertSize = insertList.size();
                if (insertSize > 0) {
                    chartCategoryModel.insertBatch(insertList);
                }
                LOG.warn("处理进度 -- 当前已处理公司数/总公司数 ：{}/{} ，插入{}条数据", toIndex, total, insertSize);
            }
            LOG.warn("-----------time consume chartCategoryAdd:" + (DateTimeUtil.getInt() - timeStart));
            LOG.warn("-----------/script/chart/category/performance/add over");
        } catch (Exception e) {
            LOG.error("/script/chart/category/performance/add error", e);
        }
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }

    /**
     * 更改系统目标的parentId由原目标完成情况更名为系统目标，所以其对应parentId也要变更）
     * @param fixDataJobDTO
     * @return java.lang.String
     * @throws Exception
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    @RequestMapping(value = "/performance/update", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String performanceUpdate(@RequestBody @Valid FixDataJobDTO fixDataJobDTO) throws Exception {
        try {
            if (!proBaseConfig.getXbbCode().equals(fixDataJobDTO.getXbbCode())) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100006);
            }
            List<String> corpidList = fixDataJobDTO.getCorpidList();
            if (CollectionsUtil.isEmpty(corpidList)) {
                // 获取所有公司
                corpidList = chartCategoryModel.getCorpidList();
            }
            //corpid=0数据也需处理
            corpidList.add(StringConstant.DEFAULT_CORPID);
            LOG.warn("-----------performanceUpdate start 开始执行图表中心目标完成情况 - 系统目标分类parentId处理-----------");
            long timeStart = DateTimeUtil.getInt();
            int total = corpidList.size();
            int pageSize = 500;
            XbbResponse<JSONObject> response;
            JSONObject resultJson = new JSONObject();
            /*
              现有的“目标完成情况” -- 其中②③通过刷sql先更新正确
                   ①parentId由0变为父的“目标完成情况”的主键id（新插入的图表一级分类）

                   -- 其中②③通过刷sql先更新正确，此脚本不处理
                   ②更名为“系统目标”
                   ③alias由“performanceChart”改为“systemPerformanceChart”
             */
            String performanceChart = ChartCategoryEnum.PERFORMANCE_FINISH_CHART.getAlias();
            String systemPerformanceChart = ChartCategoryEnum.SYSTEM_PERFORMANCE_CHART.getAlias();
            Map<String, Object> param = Maps.newHashMapWithExpectedSize(BasicConstant.THREE);
            param.put("del", 0);
            param.put("type", ChartCategoryTypeEnum.PERFORMANCE.getCode());
            for (int i = 0; i < total; i += pageSize) {
                int toIndex = i + pageSize;
                if (toIndex > total) {
                    toIndex = total;
                }
                List<String> subList;
                try {
                    subList = corpidList.subList(i, toIndex);
                } catch (Exception e) {
                    LOG.info("{}", e);
                    resultJson.put("err", "错误 error");
                    response = new XbbResponse<>(resultJson);
                    return JSON.toJSONString(response);
                }
                if (CollectionUtils.isEmpty(subList)) {
                    break;
                }
                param.put("corpidIn", subList);
                List<ChartCategoryEntity> list = chartCategoryModel.findEntitys(param);
                if (CollectionUtils.isEmpty(list)) {
                    continue;
                }
                Map<String, List<ChartCategoryEntity>> corpCategoryMap = Maps.newHashMapWithExpectedSize(list.size());
                for (ChartCategoryEntity entity : list) {
                    List<ChartCategoryEntity> categoryList = corpCategoryMap.getOrDefault(entity.getCorpid(), new ArrayList<>());
                    categoryList.add(entity);
                    corpCategoryMap.put(entity.getCorpid(), categoryList);
                }
                List<ChartCategoryEntity> updateList = new ArrayList<>();
                for (Map.Entry<String, List<ChartCategoryEntity>> entry : corpCategoryMap.entrySet()) {
                    String corpid = entry.getKey();
                    List<ChartCategoryEntity> categoryList = entry.getValue();
                    Long parentId = 0L;
                    ChartCategoryEntity updateEntity = null;
                    for (ChartCategoryEntity entity : categoryList) {
                        if (Objects.nonNull(entity.getParentId()) && entity.getParentId() > 0) {
                            //有父分类id，已经刷过无需处理
                            continue;
                        }
                        if (Objects.equals(entity.getAlias(), performanceChart)) {
                            parentId = entity.getId();
                        } else if (Objects.equals(entity.getAlias(), systemPerformanceChart)) {
                            updateEntity = entity;
                        }
                    }
                    if (Objects.nonNull(updateEntity) && parentId > 0L) {
                        updateEntity.setParentId(parentId);
                        updateList.add(updateEntity);
                    }
                }
                int size = updateList.size();
                if (size > 0) {
                    chartCategoryModel.updateBatch4Script(updateList, subList);
                }
                LOG.warn("处理进度 -- 当前已处理公司数/总公司数 ：{}/{} ，更新{}条数据，corpCategoryMap.size():{}", toIndex, total, size, corpCategoryMap.size());
            }
            LOG.warn("-----------time consume performanceUpdate:" + (DateTimeUtil.getInt() - timeStart));
            LOG.warn("-----------/script/performance/chartCategory/update over");
        } catch (Exception e) {
            LOG.error("/script/performance/chartCategory/update error", e);
        }
        return JSON.toJSONString("{\"msg\":\"success\"}");
    }
}
